package com.spring.arch.uaa.repository.custom;

import com.hazelcast.util.CollectionUtil;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.spring.arch.common.jpa.repository.AbstractCustomizedRepository;
import com.spring.arch.uaa.model.TenantEmployee;
import com.spring.arch.common.jpa.repository.AbstractCustomizedRepository;
import com.spring.arch.uaa.model.QOrganizationEmployee;
import com.spring.arch.uaa.model.QTenantEmployee;
import com.spring.arch.uaa.model.TenantEmployee;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;

import javax.persistence.EntityManager;
import java.util.List;
import java.util.UUID;

@org.springframework.stereotype.Repository
public class UaaRepositoryImpl extends AbstractCustomizedRepository implements UaaRepository {

    @Autowired
    private EntityManager entityManager;

    @Override
    public Page<TenantEmployee> searchEmploy(UUID tenantId, UUID projectId, String code, String name, String mobile,
                                             Boolean status, Pageable pageable) {
        JPAQueryFactory queryFactory = new JPAQueryFactory(entityManager);
        QTenantEmployee tenantEmployee = QTenantEmployee.tenantEmployee;
        QOrganizationEmployee organizationEmployee = QOrganizationEmployee.organizationEmployee;

        JPAQuery<TenantEmployee> query = queryFactory.select(tenantEmployee).from(tenantEmployee)
                .leftJoin(organizationEmployee).on(tenantEmployee.id.eq(organizationEmployee.employee.id));

        if(projectId != null) {

            query.where(organizationEmployee.organization.project.id.eq(projectId));
        }

        if(projectId == null && tenantId != null) {

            query.where(tenantEmployee.tenant.id.eq(tenantId));
        }

        if(StringUtils.isNotBlank(code)) {
            query.where(tenantEmployee.code.contains(code));
        }

        if(StringUtils.isNotBlank(name)) {
            query.where(tenantEmployee.name.contains(name));
        }

        if(StringUtils.isNotBlank(mobile)) {
            query.where(tenantEmployee.mobile.contains(mobile));
        }

        if(status != null) {
            query.where(tenantEmployee.status.eq(status));
        }

        query.groupBy(tenantEmployee);

        long count = query.fetchCount();

        List<TenantEmployee> list = query.offset(pageable.getOffset())
                .limit(pageable.getPageSize()).orderBy(tenantEmployee.code.asc()).fetch();

        if(CollectionUtil.isEmpty(list)) {
            return Page.empty(pageable);

        } else {

            return new PageImpl<>(list, pageable, count);
        }
    }

    @Override
    public Page<TenantEmployee> searchEmployForList(UUID tenantId, UUID projectId, String value, Pageable pageable) {
        JPAQueryFactory queryFactory = new JPAQueryFactory(entityManager);
        QTenantEmployee tenantEmployee = QTenantEmployee.tenantEmployee;
        QOrganizationEmployee organizationEmployee = QOrganizationEmployee.organizationEmployee;

        JPAQuery<TenantEmployee> query = queryFactory.select(tenantEmployee).from(tenantEmployee)
                .leftJoin(organizationEmployee).on(tenantEmployee.id.eq(organizationEmployee.employee.id))
                .where(tenantEmployee.status.eq(true));

        if(projectId != null) {


            query.where(organizationEmployee.organization.project.id.eq(projectId));
        }

        if(projectId == null && tenantId != null) {

            query.where(tenantEmployee.tenant.id.eq(tenantId));
        }

        if(StringUtils.isNotBlank(value)) {
            query.where(tenantEmployee.name.contains(value).or(tenantEmployee.mobile.contains(value)).or(tenantEmployee.code.contains(value)));
        }

        query.groupBy(tenantEmployee);

        long count = query.fetchCount();

        List<TenantEmployee> list = query.offset(pageable.getOffset())
                .limit(pageable.getPageSize()).orderBy(tenantEmployee.code.asc()).fetch();

        if(CollectionUtil.isEmpty(list)) {
            return Page.empty(pageable);

        } else {

            return new PageImpl<>(list, pageable, count);
        }
    }
}